// 如果是属性类型，则获取属性对应的值，否则直接获取值
// 考虑如下情况
// struct ax{
//      ax(int){}
//      ...
// };
//
// 假定 prop 是一个 int 类型属性，int bar = foo->prop 这种隐式转换是可以的，因为只有一层转换，
// 等价于 int bar = foo->prop.operator int(); /*注意 prop 这个属性在定义时实现了此接口，不是凭空出现的，其他非属性类型则需要自己定义*/
// 但是 ax a = foo->prop; 这样就不行了，因为不存在 foo->prop.operator ax() 这种转换，它也不会自动转换，
// 因为 ax 构造函数参数类型还可以套娃，把从 int 构造变成从 struct bx 构造，然后 bx 支持 int 构造。
// 那么这样会使得构造匹配变得复杂，所以干脆就只支持一方的隐式转换。
// 要么 ax a = int(1); int 隐式转 ax，要么 int bar = foo->prop; 属性转 int，当两方都存在隐式转换时，
// 它不会自动匹配
// ax a = foo->prop;
#ifndef xpack_utils_get_prop_value
#define xpack_utils_get_prop_value
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::utils_get_prop_value::inc
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"meta/has_constructor.hpp"
#include"meta/is_enum_class.hpp"
#include"meta/is_xstruct_prop_get.hpp"
#pragma pop_macro("xuser")

namespace mixc::utils_get_prop_value::origin{
    template<inc::is_xstruct_prop_get prop_t>
    inline decltype(auto) get_prop_value(prop_t && prop){
        return (prop()); // 属性重载了 operator()() 用于 get 数值
    }

    template<class non_prop_t>
    inline decltype(auto) get_prop_value(non_prop_t && value){
        return ((non_prop_t &&)value);
    }

    // 可能是位域，或者说如果是整数类型，则不必考虑将它转换成引用
    // 位域可能是枚举类或者整数
    //
    // 下面方式不管用
    // template<inc::is_integer_based int_t>
    // inline auto get_prop_value(int_t value){
    //     return value;
    // }

    template<inc::is_enum_class enum_t>
    inline auto get_prop_value(enum_t value){
        return value;
    }

    template<class int_t>
    requires(inc::has_constructor<int_t, void(uxx)>)
    inline auto get_prop_value(int_t value){
        return value;
    }
}

#endif

xexport_space(mixc::utils_get_prop_value::origin)